package com.xup.luckymoney;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;

import com.xup.luckymoney.job.AccessibilityJob;
import com.xup.luckymoney.job.QQAccessibilityJob;
import com.xup.luckymoney.job.WechatAccessibilityJob;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class LuckyMoneyService extends AccessibilityService {

    private static final String TAG = "LuckyMoneyService";
    private static final boolean DEBUG = true;

    private static final Class[] ACCESSIBILITY_JOBS = {
            WechatAccessibilityJob.class,
            QQAccessibilityJob.class
    };

    private static LuckyMoneyService service;

    private Config mConfig;
    private List<AccessibilityJob> mAccessibilityJobs;
    private PackageInfo mWechatPackageInfo = null;
    private PackageInfo mQQPackageInfo = null;

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateWechatPackageInfo();
            updateQQPackageInfo();
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();

        if (DEBUG) Log.d(TAG, "LuckyMoneyService, onCreate");
        mAccessibilityJobs = new ArrayList<>();
        mConfig = Config.getInstance(this);

        // init job
        if (mAccessibilityJobs == null || mAccessibilityJobs.isEmpty()) {
            initJobs();
        }

        IntentFilter filter = new IntentFilter();
        filter.addDataScheme("package");
        filter.addAction("android.intent.action.PACKAGE_ADDED");
        filter.addAction("android.intent.action.PACKAGE_REPLACED");
        filter.addAction("android.intent.action.PACKAGE_REMOVED");

        registerReceiver(broadcastReceiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (DEBUG) Log.d(TAG, "qianghongbao service destory");
        if (mAccessibilityJobs != null && !mAccessibilityJobs.isEmpty()) {
            for (AccessibilityJob job : mAccessibilityJobs) {
                job.onStopJob();
            }
            mAccessibilityJobs.clear();
        }
        service = null;
        mAccessibilityJobs = null;
        Intent intent = new Intent(Config.ACTION_RED_PACKET_SERVICE_DISCONNECT);
        sendBroadcast(intent);

        unregisterReceiver(broadcastReceiver);
    }

    @Override
    public void onInterrupt() {
        if (DEBUG) Log.d(TAG, "qianghongbao service interrupt");
        Toast.makeText(this, R.string.disconnect_from_lucky_money_service,
                Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        service = this;
        Intent intent = new Intent(Config.ACTION_RED_PACKET_SERVICE_CONNECT);
        sendBroadcast(intent);
        Toast.makeText(this, R.string.connect_to_lucky_money_service,
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (DEBUG) Log.d(TAG, "accessibility event--->" + event);
        String pkn = String.valueOf(event.getPackageName());
        if (mAccessibilityJobs != null && !mAccessibilityJobs.isEmpty()) {
            for (AccessibilityJob job : mAccessibilityJobs) {
                if (pkn.equals(job.getTargetPackageName())) {
                    job.onReceiveJob(event);
                }
            }
        }
    }

    private void initJobs() {
        if (DEBUG) Log.d(TAG, "initJobs when mAccessibilityJobs is empty");
        if (mAccessibilityJobs == null) {
            mAccessibilityJobs = new ArrayList<>();
        }
        for (Class clazz : ACCESSIBILITY_JOBS) {
            try {
                Object object = clazz.newInstance();
                if (object instanceof AccessibilityJob) {
                    AccessibilityJob job = (AccessibilityJob) object;
                    job.onCreateJob(this);
                    mAccessibilityJobs.add(job);
                }
            } catch (Exception e) {
                Log.e(TAG, "exception occurs when initJobs");
                e.printStackTrace();
            }
        }
    }

    public Config getConfig() {
        return mConfig;
    }

    /**
     * judge is the service rinning
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public static boolean isRunning() {
        if (service == null) {
            return false;
        }
        AccessibilityManager accessibilityManager = (AccessibilityManager) service
                .getSystemService(Context.ACCESSIBILITY_SERVICE);
        AccessibilityServiceInfo info = service.getServiceInfo();
        if (info == null) {
            return false;
        }
        List<AccessibilityServiceInfo> list = accessibilityManager
                .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
        Iterator<AccessibilityServiceInfo> iterator = list.iterator();

        boolean isConnect = false;
        while (iterator.hasNext()) {
            AccessibilityServiceInfo i = iterator.next();
            if (i.getId().equals(info.getId())) {
                isConnect = true;
                break;
            }
        }
        if (!isConnect) {
            return false;
        }
        return true;
    }

    public void updateWechatPackageInfo() {
        try {
            mWechatPackageInfo = getPackageManager()
                    .getPackageInfo(Config.WECHAT_PACKAGENAME, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    public int getWechatVersion() {
        if (mWechatPackageInfo == null) {
            return 0;
        }
        if (DEBUG) Log.d(TAG, "mWechatPackageInfo.versionCode = " + mWechatPackageInfo.versionCode);
        return mWechatPackageInfo.versionCode;
    }

    /**
     * update QQ package information
     */
    public void updateQQPackageInfo() {
        try {
            mQQPackageInfo = getPackageManager().getPackageInfo(Config.QQ_PACKAGENAME, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * get QQ version(not used now)
     */
    public int getQQVersion() {
        if (mQQPackageInfo == null) {
            return 0;
        }
        if (DEBUG) Log.d(TAG, "mQQPackageInfo.versionCode = " + mQQPackageInfo.versionCode);
        return mQQPackageInfo.versionCode;
    }
}
